package Tarea1;

/*
 * Clase encargada de establecer conexión serial con Arduino, enviar y recibir comandos.
 */

/**
 *
 * @author manuel
 */

import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;

public class ManejoUsuario implements SerialPortEventListener{
		SerialPort puertoSerial;
		private static final String NOMBRE_DE_PUERTOS[] = { 
				Constantes.PUERTO_SERIAL_LINUX,
				Constantes.PUERTO_SERIAL_WINDOWS, 
				};
		private InputStream entrada;
		private OutputStream salida;
		
		private String bufferEntrada="";
                private String mensajeRecibido="";

                /*
                 * Método que establece las variables para iniciar la conexión con el Arduino en
                 * su respectivo puerto
                 */
		public void iniciar() {
                    
			CommPortIdentifier idPuerto = null;
			Enumeration puertosDisponbibles = CommPortIdentifier.getPortIdentifiers();


			while (puertosDisponbibles.hasMoreElements()) {
				CommPortIdentifier idPuertoArduino = (CommPortIdentifier) puertosDisponbibles.nextElement();
				for (String portName : NOMBRE_DE_PUERTOS) {
					if (idPuertoArduino.getName().equals(portName)) {
						idPuerto = idPuertoArduino;
						break;
					}
				}
			}

			if (idPuerto == null) {
				System.out.println(Constantes.ARDUINO_CONEXION_ERROR);
				return;
			}else{
				System.out.println(Constantes.ARDUINO_CONEXION_EXITO);
			}

			try {
				puertoSerial = (SerialPort) idPuerto.open(this.getClass().getName(),Constantes.TIEMPO_ESCUCHANDO);
				puertoSerial.setSerialPortParams(Constantes.DATA_RATE,
						SerialPort.DATABITS_8,
						SerialPort.STOPBITS_1,  
						SerialPort.PARITY_NONE);
				entrada = puertoSerial.getInputStream();
				salida = puertoSerial.getOutputStream();

				puertoSerial.addEventListener(this);
				puertoSerial.notifyOnDataAvailable(true);
				
			} catch (Exception e) {
				System.err.println(e.toString());
			}
		}
		
                /*
                 * Método encargado de cerrar la conexión con el puerto serial del Arduino
                 */
		public synchronized void close() {
			if (puertoSerial != null) {
				puertoSerial.removeEventListener();
				puertoSerial.close();
			}
		}
		
                /*
                 * Método encargado de enviar los comandos respectivos al Arduino
                 */
		public synchronized void enviarComando(String msg){
			try {
				msg+='\n';
				salida.write(msg.getBytes());
				salida.flush();
			} catch (Exception e) {
				System.err.println(e.toString());
			}
		}
		

                /*
                 * Envento que queda a la espera de recibir la respuesta del Arduino al enviar un comando
                 */
		public synchronized void serialEvent (SerialPortEvent oEvent) {
			if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
				try {
					int datosDisponibles = entrada.available();
					for(int i=0;i<datosDisponibles;i++){
						int datoRecibido=entrada.read();
						if(datoRecibido!=10 && datoRecibido!=13){
							bufferEntrada+=(char)datoRecibido;
						}else if(datoRecibido==10){
                                                    mensajeRecibido=bufferEntrada;
                                                    bufferEntrada="";
						}
					}
				} catch (Exception e) {
					System.err.println(e.toString());
				}
			}
		}
                
                /*
                 * Método encargado de devolver la respuesta al usuario
                 */
                public synchronized String getRespuesta(){                  
                    return this.mensajeRecibido;
                }
}